package day_05_02_ThreadPool;

import java.util.concurrent.*;

/**
 * @Description 线程池技术学习
 * @Author shihan
 * @Date 2020/11/8 9:36
 * @Version 1.0
 */
public class MyThreadPoolDemo {

    public static void main(String[] args) {
        /**
         * 1、创建线程池：
         *    1）、使用多态技术，用 ExecutorService 子接口；
         *    2）、创建线程池，使用 Executors 工具类来创建线程池；
         *    3）、有三类线程池：
         *         固定线程数：newFixedThreadPool(线程数)
         *         只有一个线程：newSingleThreadExecutor()
         *         可动态扩容的线程池：newCachedThreadPool()
         */
        //ExecutorService threadPool = Executors.newFixedThreadPool(5);

        /**
         * 自定义线程池：
         * 1、能容纳的最大容量：正在运行的 maximumPoolSize + 阻塞队列的长度
         * 2、当 maximumPoolSize + 阻塞队列的长度 均已满后，还有请求过来，则将触发拒绝策略；
         */
        /**
         *【PS：实际应用中，如何设置 corePoolSize、maximumPoolSize 的参数值】
         * 一、CPU密集型：服务器处理器核数 + 1
         * 任务管理器--性能--CPU--逻辑处理器
         * 二、IO密集型：服务器处理器核数 / IO系数（目前只做了解）
         */
        System.out.println(Runtime.getRuntime().availableProcessors());

        ExecutorService threadPool = new ThreadPoolExecutor(
                2,
                Runtime.getRuntime().availableProcessors() + 1,
                2,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                new ThreadPoolExecutor.AbortPolicy());      // 默认策略为 AbortPolicy() ，即抛异常

        try {
            /**
             * 2、往线程池里，丢任务：
             *    1）、往线程池里丢任务的方式：
             *         无返回值：execute(Runnable runnable)
             *         可以接收返回值：submit(Callable callable)
             */
            for (int i = 1; i <= 9 ; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "\t占用线程池的线程！");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            /**
             * 3、使用完后，关闭线程池
             */
            threadPool.shutdown();
        }

    }
}
